package my.files;

import java.io.File;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Set;
import java.util.*;

//Tested.  Needs retesting cuz of subclassing java.io.Files to my.files.Files
public class Finder extends SimpleFileVisitor<Path> {  //Probably best to leave non-static

    public ArrayList<my.files.Files> Results = new ArrayList();
    public boolean IncludeDir = true;
    public boolean ShowHidden = true;
    public FindSyntax Syntax = FindSyntax.Glob;
    
    private FileSystem fFileSys = FileSystems.getDefault();
    private PathMatcher fPm;

    public enum FindSyntax {
        Glob, Rgx;

        public String getString(FindSyntax type) {
            return (type == FindSyntax.Glob) ? "glob:" : "regex";
        }
    }

    public Finder(boolean showDir, boolean showHidden) {
        IncludeDir = showDir;
        ShowHidden = showHidden;
    }
    
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attr) {
        if (fPm.matches(file.getFileName()) & (!file.toFile().isHidden() | ShowHidden)) {
            my.files.Files f = new my.files.Files(file);
            Results.add(f);
        }
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attr) {
        if (fPm.matches(dir.getFileName()) & (!dir.toFile().isHidden() | ShowHidden)) 
            Results.add(new Files(dir));
        
        return FileVisitResult.CONTINUE;
    }

    /** Needs Testing cuz of new Files class extends java.io.File
     * Task: Looking into a more loosely typed collection type to apply polymorphism for File or my.files.Files
     * @param startDir starting directory
     * @param patt glob:*.* or regex:?
     * @param lvl 1 for non recursive/ 1000+ for recursive
     * @param opt EnumSet.noneOf(FileVisitOption.class) = don't follow
     * SymbolicLink
     * @return Results
     * @throws java.io.IOException
     */
    public ArrayList<Files> find(Path startDir, String patt, int lvl, Set<FileVisitOption> opt) throws java.io.IOException {
        fPm = fFileSys.getPathMatcher(Syntax.getString(Syntax)+patt);
        java.nio.file.Files.walkFileTree(startDir, opt, lvl, this);  //Java returns startDir.

        return Results;
    }
}
